﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Kindohm.Life.Library
{
    public abstract class BoardObject
    {
        Point point;
        Board board;
        string name;
        Guid id;

        public Guid Id
        {
            get { return this.id; }
            set { this.id = value; }
        }
        
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }
        
        public Board Board
        {
            get { return this.board; }
            set { this.board = value; }
        }

        public Point Position
        {
            get { return this.point; }
            set { this.point = value; }
        }

        public void Move(Point target)
        {
            bool result = this.ValidateTargetMovePoint(target);

            if (!result)
            {
                throw new MoveException("The target point is not a valid move.");
            }

            Point oldPoint = this.point;
            this.point = target;
            this.board.BoardObjects[oldPoint] = null;
            this.board.BoardObjects[target] = this;
        }

        bool ValidateTargetMovePoint(Point target)
        {
            if (this.board.BoardObjects[target] != null)
            {
                return false;
            }

            int difX = target.X - this.point.X;
            int difY = target.Y - this.point.Y;

            if ((difX > 1 || difX < -1) || (difY > 1 || difY < -1))
            {
                return false;
            }

            return true;
        }


        public Collection<Point> GetValidDestinationPoints()
        {
            if (this.board == null)
            {
                return null;
            }

            Collection<Point> points = new Collection<Point>();
            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    Point p = new Point();
                    p.X = this.Position.X + x;
                    p.Y = this.Position.Y + y;

                    if ((p.X >= 0 && p.X < this.board.Width)
                        && (p.Y >= 0 && p.Y < this.board.Height))
                    {
                        if (this.Position.Equals(p) == false &&
                            this.Board.BoardObjects[p] == null)
                        {
                            points.Add(p);
                        }
                    }
                }
            }
            return points;
        }

        public void RemoveFromBoard()
        {
            if (this.board != null)
            {
                this.board.RemoveObject(this.Position);
            }
        }

        public event EventHandler<BoardObjectInfoEventArgs> WriteInfo;

        protected virtual void LogVerboseMessage(string message)
        {
            if (this.WriteInfo != null)
            {
                this.WriteInfo(this, new BoardObjectInfoEventArgs(this.Name + " : " + message));
            }
        }
    }
}
